package com.ljy.gui;

import com.ljy.dao.LedgerDAO;
import com.ljy.dao.impl.LedgerDAOImpl;
import com.ljy.pojo.Ledger;
import com.toedter.calendar.JDateChooser;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

public class LedgerManagementSystemUI extends JFrame {
    private final JTable table;
    private final JPanel paginationPanel;
    private final int rowsPerPage = 20;
    private int currentPage = 1;
    private final LedgerDAO ledgerDAO = new LedgerDAOImpl();
    private List<Ledger> currentLedgers = ledgerDAO.getAllLedgers();

    private JCheckBox headerCheckBox;

    String[] columnNames = {
            "序号", "年份", "业务类别", "任务编号", "交接单序号", "数据标识", "数据一级目录", "数据二级目录",
            "数据名称", "控规名称/核定表编号/历史遗留问题编号", "控规代号", "数据格式", "数据坐标系",
            "覆盖区域", "覆盖面积(㎡)", "数据量大小(MB)", "文件个数", "数据是否涉密", "提交日期",
            "提交人", "提交部门", "提交介质/提交位置", "文件入库位置", "空间入库位置", "接收人",
            "接收时间", "入库人", "入库情况说明", "审核人", "审核日期"
    };

    private final String[] columnNamesWithCheckbox = new String[columnNames.length + 1];
    {
        columnNamesWithCheckbox[0] = "选择"; // 复选框列标题
        System.arraycopy(columnNames, 0, columnNamesWithCheckbox, 1, columnNames.length);
    }

    private final Map<Long, Boolean> checkboxStates = new HashMap<>();


    public LedgerManagementSystemUI() {
        // 设置窗口
        setTitle("台账管理系统");
        setSize(1500, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());

        // 创建主面板，包含按钮和查询面板
        JPanel northPanel = new JPanel(new BorderLayout());

        // 第一行：按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        String[] buttonIconNames = {
                "add.png",
                "import.png",
                "export.png",
                "delete.png",
                "save.png"
        };
        String[] buttonTooltips = {"新增", "导入", "导出", "删除", "保存"};
        JButton[] buttons = new JButton[buttonIconNames.length];
        for (int i = 0; i < buttonIconNames.length; i++) {
            buttons[i] = new JButton();
            ImageIcon icon = loadIcon(buttonIconNames[i]);
            if (icon != null) {
                buttons[i].setIcon(icon);
            } else {
                buttons[i].setText(buttonTooltips[i]);
            }
            buttons[i].setToolTipText(buttonTooltips[i]);
            buttons[i].setPreferredSize(new Dimension(40, 40));
            buttonPanel.add(buttons[i]);
        }
        northPanel.add(buttonPanel, BorderLayout.NORTH);

        // 第二行：查询面板
        JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JTextField yearField = new JTextField(10);
        JTextField businessTypeField = new JTextField(10);
        JTextField primaryDirectoryField = new JTextField(10);
        JTextField secondaryDirectoryField = new JTextField(10);
        JDateChooser startDateChooser = new JDateChooser();
        JDateChooser endDateChooser = new JDateChooser();
        startDateChooser.setDateFormatString("yyyy-MM-dd");
        endDateChooser.setDateFormatString("yyyy-MM-dd");
        startDateChooser.setDate(null);
        endDateChooser.setDate(null);
        startDateChooser.setPreferredSize(new Dimension(100, 25));
        endDateChooser.setPreferredSize(new Dimension(100, 25));

        queryPanel.add(new JLabel("年份："));
        queryPanel.add(yearField);
        queryPanel.add(new JLabel("业务类别："));
        queryPanel.add(businessTypeField);
        queryPanel.add(new JLabel("数据一级目录："));
        queryPanel.add(primaryDirectoryField);
        queryPanel.add(new JLabel("数据二级目录："));
        queryPanel.add(secondaryDirectoryField);
        queryPanel.add(new JLabel("提交日期："));
        queryPanel.add(startDateChooser);
        queryPanel.add(new JLabel("至"));
        queryPanel.add(endDateChooser);
        JButton queryButton = new JButton("查询");
        queryPanel.add(queryButton);
        northPanel.add(queryPanel, BorderLayout.CENTER);
        add(northPanel, BorderLayout.NORTH);

        // 表格区域
        String[] columnNames = {
                "序号", "年份", "业务类别", "任务编号", "交接单序号", "数据标识", "数据一级目录", "数据二级目录",
                "数据名称", "控规名称/核定表编号/历史遗留问题编号", "控规代号", "数据格式", "数据坐标系",
                "覆盖区域", "覆盖面积(㎡)", "数据量大小(MB)", "文件个数", "数据是否涉密", "提交日期",
                "提交人", "提交部门", "提交介质/提交位置", "文件入库位置", "空间入库位置", "接收人",
                "接收时间", "入库人", "入库情况说明", "审核人", "审核日期"
        };
        table = new JTable(new Object[0][columnNames.length], columnNames);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        JScrollPane tableScrollPane = new JScrollPane(table);
        tableScrollPane.setMinimumSize(new Dimension(1200, 400));
        add(tableScrollPane, BorderLayout.CENTER);

        // 分页栏目
        paginationPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        add(paginationPanel, BorderLayout.SOUTH);

        // 加载初始数据
        updateTableData();
        // 新增按钮功能
        buttons[0].addActionListener(e -> showAddDialog());
        // 删除按钮功能
        buttons[3].addActionListener(e -> showDeleteDialog());
        // 保存按钮功能
        buttons[4].addActionListener(e -> saveAllData());
        // 导入按钮功能
        buttons[1].addActionListener(e -> importExcel());
        // 导出按钮功能
        buttons[2].addActionListener(e -> exportExcel());
        // 查询按钮功能
        queryButton.addActionListener(e -> {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String startDate = startDateChooser.getDate() != null ? dateFormat.format(startDateChooser.getDate()) : "";
            String endDate = endDateChooser.getDate() != null ? dateFormat.format(endDateChooser.getDate()) : "";

            currentLedgers = ledgerDAO.searchLedgers(
                    yearField.getText(),
                    businessTypeField.getText(),
                    primaryDirectoryField.getText(),
                    secondaryDirectoryField.getText(),
                    startDate,
                    endDate
            );
            currentPage = 1;
            updateTableData();
            updatePagination();
        });

        // 表格设置
        table.setEnabled(true);
        table.setCellSelectionEnabled(false);
        table.setEditingRow(-1);
        table.setEditingColumn(-1);
        table.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent e) {
                if (e.getClickCount() == 1) {
                    int selectedRow = table.getSelectedRow();
                    int selectedColumn = table.getSelectedColumn();
                    if (selectedColumn == 0) {
                        return;
                    }
                    if (selectedRow != -1) {
                        int ledgerIndex = (currentPage - 1) * rowsPerPage + selectedRow;
                        if (ledgerIndex < currentLedgers.size()) {
                            Ledger ledger = currentLedgers.get(ledgerIndex);
                            showEditDialog(ledger, ledgerIndex);
                        }
                    }
                }
            }
        });

        // 初始化分页
        updatePagination();

        setVisible(true);
    }

    private void showAddDialog() {
        JDialog dialog = new JDialog(this, "新增记录", true);
        dialog.setLayout(new GridLayout(31, 2, 5, 5));
        dialog.setSize(600, 800);
        dialog.setLocationRelativeTo(this);

        JTextField[] fields = new JTextField[28]; // 增加一个元素以容纳所有文本字段
        JCheckBox confidentialBox = new JCheckBox();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String[] labels = {
                "年份", "业务类别", "任务编号", "交接单序号", "数据标识", "数据一级目录", "数据二级目录",
                "数据名称", "控规名称/核定表编号/历史遗留问题编号", "控规代号", "数据格式", "数据坐标系",
                "覆盖区域", "覆盖面积(㎡)", "数据量大小(MB)", "文件个数", "数据是否涉密", "提交日期",
                "提交人", "提交部门", "提交介质/提交位置", "文件入库位置", "空间入库位置", "接收人",
                "接收时间", "入库人", "入库情况说明", "审核人", "审核日期"
        };

        // 初始化输入框和标签
        for (int i = 0; i < labels.length; i++) {
            dialog.add(new JLabel(labels[i] + "："));
            if (i == 16) { // 数据是否涉密
                dialog.add(confidentialBox);
            } else {
                // 调整索引：跳过“数据是否涉密”后，字段索引递增
                int fieldIndex = i >= 16 ? i - 1 : i;
                fields[fieldIndex] = new JTextField(20);
                dialog.add(fields[fieldIndex]);
            }
        }

        JButton saveButton = new JButton("保存");
        saveButton.addActionListener(e -> {
            try {
                Ledger ledger = new Ledger();
                ledger.setYear(fields[0].getText());
                ledger.setBusinessType(fields[1].getText());
                ledger.setTaskNumber(fields[2].getText());
                ledger.setHandoverNumber(fields[3].getText());
                ledger.setDataIdentifier(fields[4].getText());
                ledger.setPrimaryDirectory(fields[5].getText());
                ledger.setSecondaryDirectory(fields[6].getText());
                ledger.setDataName(fields[7].getText());
                ledger.setControlPlanNumber(fields[8].getText());
                ledger.setControlPlanCode(fields[9].getText());
                ledger.setDataFormat(fields[10].getText());
                ledger.setCoordinateSystem(fields[11].getText());
                ledger.setCoverageArea(fields[12].getText());
                ledger.setCoverageAreaSize(fields[13].getText().isEmpty() ? 0 : Double.parseDouble(fields[13].getText()));
                ledger.setDataSizeMb(fields[14].getText().isEmpty() ? 0 : Double.parseDouble(fields[14].getText()));
                ledger.setFileCount(fields[15].getText().isEmpty() ? 0 : Integer.parseInt(fields[15].getText()));
                ledger.setConfidential(confidentialBox.isSelected());
                ledger.setSubmissionDate(fields[16].getText().isEmpty() ? null : dateFormat.parse(fields[16].getText()));
                ledger.setSubmitter(fields[17].getText());
                ledger.setSubmissionDepartment(fields[18].getText());
                ledger.setSubmissionMedium(fields[19].getText());
                ledger.setFileStorageLocation(fields[20].getText());
                ledger.setSpatialStorageLocation(fields[21].getText());
                ledger.setReceiver(fields[22].getText());
                ledger.setReceiptTime(fields[23].getText().isEmpty() ? null : dateFormat.parse(fields[23].getText()));
                ledger.setStoragePerson(fields[24].getText());
                ledger.setStorageDescription(fields[25].getText());
                ledger.setAuditor(fields[26].getText());
                ledger.setAuditDate(fields[27].getText().isEmpty() ? null : dateFormat.parse(fields[27].getText()));

                ledgerDAO.addLedger(ledger);
                JOptionPane.showMessageDialog(dialog, "记录添加成功！");
                dialog.dispose();
                refreshData();
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(dialog, "输入格式错误：" + ex.getMessage());
                ex.printStackTrace();
            }
        });
        dialog.add(new JLabel());
        dialog.add(saveButton);
        dialog.setVisible(true);
    }

    // 新增：批量删除逻辑
    private void showDeleteDialog() {
        List<Long> selectedIds = new ArrayList<>();
        for (Map.Entry<Long, Boolean> entry : checkboxStates.entrySet()) {
            if (Boolean.TRUE.equals(entry.getValue())) {
                selectedIds.add(entry.getKey());
            }
        }

        if (selectedIds.isEmpty()) {
            JOptionPane.showMessageDialog(this, "请至少选择一条记录！");
            return;
        }

        int confirm = JOptionPane.showConfirmDialog(
                this,
                "确认删除 " + selectedIds.size() + " 条选中记录？",
                "删除确认",
                JOptionPane.YES_NO_OPTION
        );

        if (confirm == JOptionPane.YES_OPTION) {
            try {
                // 删除数据库中的记录
                for (Long id : selectedIds) {
                    ledgerDAO.deleteLedger(id);
                    checkboxStates.remove(id); // 同步移除状态
                }
                // 刷新数据
                refreshData();
                JOptionPane.showMessageDialog(this, "成功删除 " + selectedIds.size() + " 条记录！");
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(this, "删除失败：" + ex.getMessage());
                ex.printStackTrace();
            }
        }
    }


    private void showDeleteDialog_Backup() {
        int selectedRow = table.getSelectedRow();
        if (selectedRow == -1) {
            JOptionPane.showMessageDialog(this, "请先选择一行数据！");
            return;
        }
        // 计算 currentLedgers 中的正确索引
        int ledgerIndex = (currentPage - 1) * rowsPerPage + selectedRow;
        if (ledgerIndex >= currentLedgers.size()) {
            JOptionPane.showMessageDialog(this, "无效的选择！");
            return;
        }
        long id = currentLedgers.get(ledgerIndex).getId();
        int confirm = JOptionPane.showConfirmDialog(this, "确认删除该记录？", "删除确认", JOptionPane.YES_NO_OPTION);
        if (confirm == JOptionPane.YES_OPTION) {
            ledgerDAO.deleteLedger(id);
            JOptionPane.showMessageDialog(this, "记录删除成功！");
            refreshData(); // 刷新数据
        }
    }

    private void showEditDialog(Ledger ledger, int ledgerIndex) {
        JDialog dialog = new JDialog(this, "修改记录", true);
        dialog.setSize(600, 800);
        dialog.setLocationRelativeTo(this);
        dialog.setLayout(new BorderLayout());

        // 创建字段面板，使用 GridLayout 排列输入框
        JPanel fieldsPanel = new JPanel(new GridLayout(30, 2, 5, 5)); // 30 行，包含所有字段
        JTextField[] fields = new JTextField[28];
        JCheckBox confidentialBox = new JCheckBox();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String[] labels = {
                "年份", "业务类别", "任务编号", "交接单序号", "数据标识", "数据一级目录", "数据二级目录",
                "数据名称", "控规名称/核定表编号/历史遗留问题编号", "控规代号", "数据格式", "数据坐标系",
                "覆盖区域", "覆盖面积(㎡)", "数据量大小(MB)", "文件个数", "数据是否涉密", "提交日期",
                "提交人", "提交部门", "提交介质/提交位置", "文件入库位置", "空间入库位置", "接收人",
                "接收时间", "入库人", "入库情况说明", "审核人", "审核日期"
        };

        // 初始化输入框并填充已有数据
        for (int i = 0; i < labels.length; i++) {
            fieldsPanel.add(new JLabel(labels[i] + "："));
            if (i == 16) { // 数据是否涉密
                confidentialBox.setSelected(ledger.isConfidential());
                fieldsPanel.add(confidentialBox);
            } else {
                int fieldIndex = i >= 16 ? i - 1 : i;
                fields[fieldIndex] = new JTextField(20);
                switch (fieldIndex) {
                    case 0: fields[fieldIndex].setText(ledger.getYear()); break;
                    case 1: fields[fieldIndex].setText(ledger.getBusinessType()); break;
                    case 2: fields[fieldIndex].setText(ledger.getTaskNumber()); break;
                    case 3: fields[fieldIndex].setText(ledger.getHandoverNumber()); break;
                    case 4: fields[fieldIndex].setText(ledger.getDataIdentifier()); break;
                    case 5: fields[fieldIndex].setText(ledger.getPrimaryDirectory()); break;
                    case 6: fields[fieldIndex].setText(ledger.getSecondaryDirectory()); break;
                    case 7: fields[fieldIndex].setText(ledger.getDataName()); break;
                    case 8: fields[fieldIndex].setText(ledger.getControlPlanNumber()); break;
                    case 9: fields[fieldIndex].setText(ledger.getControlPlanCode()); break;
                    case 10: fields[fieldIndex].setText(ledger.getDataFormat()); break;
                    case 11: fields[fieldIndex].setText(ledger.getCoordinateSystem()); break;
                    case 12: fields[fieldIndex].setText(ledger.getCoverageArea()); break;
                    case 13: fields[fieldIndex].setText(ledger.getCoverageAreaSize() != 0 ? String.valueOf(ledger.getCoverageAreaSize()) : ""); break;
                    case 14: fields[fieldIndex].setText(ledger.getDataSizeMb() != 0 ? String.valueOf(ledger.getDataSizeMb()) : ""); break;
                    case 15: fields[fieldIndex].setText(ledger.getFileCount() != 0 ? String.valueOf(ledger.getFileCount()) : ""); break;
                    case 16: fields[fieldIndex].setText(ledger.getSubmissionDate() != null ? dateFormat.format(ledger.getSubmissionDate()) : ""); break;
                    case 17: fields[fieldIndex].setText(ledger.getSubmitter()); break;
                    case 18: fields[fieldIndex].setText(ledger.getSubmissionDepartment()); break;
                    case 19: fields[fieldIndex].setText(ledger.getSubmissionMedium()); break;
                    case 20: fields[fieldIndex].setText(ledger.getFileStorageLocation()); break;
                    case 21: fields[fieldIndex].setText(ledger.getSpatialStorageLocation()); break;
                    case 22: fields[fieldIndex].setText(ledger.getReceiver()); break;
                    case 23: fields[fieldIndex].setText(ledger.getReceiptTime() != null ? dateFormat.format(ledger.getReceiptTime()) : ""); break;
                    case 24: fields[fieldIndex].setText(ledger.getStoragePerson()); break;
                    case 25: fields[fieldIndex].setText(ledger.getStorageDescription()); break;
                    case 26: fields[fieldIndex].setText(ledger.getAuditor()); break;
                    case 27: fields[fieldIndex].setText(ledger.getAuditDate() != null ? dateFormat.format(ledger.getAuditDate()) : ""); break;
                }
                fieldsPanel.add(fields[fieldIndex]);
            }
        }

        // 将字段面板放入滚动面板，防止内容过多
        JScrollPane scrollPane = new JScrollPane(fieldsPanel);
        dialog.add(scrollPane, BorderLayout.CENTER);

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        JButton saveButton = new JButton("保存");
        JButton deleteButton = new JButton("删除");

        // 保存按钮逻辑
        saveButton.addActionListener(e -> {
            try {
                ledger.setYear(fields[0].getText());
                ledger.setBusinessType(fields[1].getText());
                ledger.setTaskNumber(fields[2].getText());
                ledger.setHandoverNumber(fields[3].getText());
                ledger.setDataIdentifier(fields[4].getText());
                ledger.setPrimaryDirectory(fields[5].getText());
                ledger.setSecondaryDirectory(fields[6].getText());
                ledger.setDataName(fields[7].getText());
                ledger.setControlPlanNumber(fields[8].getText());
                ledger.setControlPlanCode(fields[9].getText());
                ledger.setDataFormat(fields[10].getText());
                ledger.setCoordinateSystem(fields[11].getText());
                ledger.setCoverageArea(fields[12].getText());
                ledger.setCoverageAreaSize(fields[13].getText().isEmpty() ? 0 : Double.parseDouble(fields[13].getText()));
                ledger.setDataSizeMb(fields[14].getText().isEmpty() ? 0 : Double.parseDouble(fields[14].getText()));
                ledger.setFileCount(fields[15].getText().isEmpty() ? 0 : Integer.parseInt(fields[15].getText()));
                ledger.setConfidential(confidentialBox.isSelected());
                ledger.setSubmissionDate(fields[16].getText().isEmpty() ? null : dateFormat.parse(fields[16].getText()));
                ledger.setSubmitter(fields[17].getText());
                ledger.setSubmissionDepartment(fields[18].getText());
                ledger.setSubmissionMedium(fields[19].getText());
                ledger.setFileStorageLocation(fields[20].getText());
                ledger.setSpatialStorageLocation(fields[21].getText());
                ledger.setReceiver(fields[22].getText());
                ledger.setReceiptTime(fields[23].getText().isEmpty() ? null : dateFormat.parse(fields[23].getText()));
                ledger.setStoragePerson(fields[24].getText());
                ledger.setStorageDescription(fields[25].getText());
                ledger.setAuditor(fields[26].getText());
                ledger.setAuditDate(fields[27].getText().isEmpty() ? null : dateFormat.parse(fields[27].getText()));

                List<Ledger> updatedLedgers = new ArrayList<>(currentLedgers);
                updatedLedgers.set(ledgerIndex, ledger);
                ledgerDAO.saveAllLedgers(updatedLedgers);

                JOptionPane.showMessageDialog(dialog, "记录修改成功！");
                dialog.dispose();
                refreshData();
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(dialog, "输入格式错误：" + ex.getMessage());
                ex.printStackTrace();
            }
        });

        // 删除按钮逻辑
        deleteButton.addActionListener(e -> {
            int confirm = JOptionPane.showConfirmDialog(dialog, "确认删除该记录？", "删除确认", JOptionPane.YES_NO_OPTION);
            if (confirm == JOptionPane.YES_OPTION) {
                try {
                    ledgerDAO.deleteLedger(ledger.getId());
                    JOptionPane.showMessageDialog(dialog, "记录删除成功！");
                    dialog.dispose();
                    refreshData();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(dialog, "删除失败：" + ex.getMessage());
                    ex.printStackTrace();
                }
            }
        });

        // 添加按钮到面板
        buttonPanel.add(saveButton);
        buttonPanel.add(deleteButton);
        dialog.add(buttonPanel, BorderLayout.SOUTH);

        dialog.setVisible(true);
    }

    private void saveAllData() {
        try {
            ledgerDAO.saveAllLedgers(currentLedgers);
            // 刷新数据
            refreshData();
            JOptionPane.showMessageDialog(this, "数据保存成功！");
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "数据保存失败：" + e.getMessage());
            e.printStackTrace();
        }
    }

    private void importExcel() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            ledgerDAO.importFromExcel(file.getAbsolutePath());
            JOptionPane.showMessageDialog(this, "数据导入成功！");
            refreshData();
        }
    }

    private void exportExcel() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int result = fileChooser.showSaveDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            String filePath = file.getAbsolutePath();
            if (!filePath.endsWith(".xlsx")) {
                filePath += ".xlsx";
            }
            try {
                List<Ledger> allLedgers = ledgerDAO.getAllLedgers();
                System.out.println("导出记录数: " + allLedgers.size());
                ledgerDAO.exportToExcel(allLedgers, filePath);
                JOptionPane.showMessageDialog(this, "数据导出成功！共导出 " + allLedgers.size() + " 条记录");
            } catch (Exception e) {
                System.err.println("导出失败: " + e.getMessage());
                e.printStackTrace();
                JOptionPane.showMessageDialog(this, "数据导出失败：" + e.getMessage());
            }
        }
    }

    private ImageIcon loadIcon(String iconName) {
        try {
            String path = "/icons/" + iconName;
            java.net.URL imgURL = getClass().getResource(path);
            if (imgURL != null) {
                ImageIcon originalIcon = new ImageIcon(imgURL);
                Image scaledImage = originalIcon.getImage().getScaledInstance(32, 32, Image.SCALE_SMOOTH);
                return new ImageIcon(scaledImage);
            } else {
                System.err.println("无法找到图标: " + path);
                return null;
            }
        } catch (Exception e) {
            System.err.println("加载图标失败: " + iconName);
            e.printStackTrace();
            return null;
        }
    }

    private void updatePagination() {
        paginationPanel.removeAll();
        int totalRecords = ledgerDAO.getTotalRecords();
        int totalPages = (int) Math.ceil((double) totalRecords / rowsPerPage);
        if (totalPages == 0) totalPages = 1;

        // 上一页按钮
        JButton prevButton = new JButton();
        ImageIcon prevIcon = loadIcon("previous.png");
        if (prevIcon != null) {
            prevButton.setIcon(prevIcon);
        } else {
            prevButton.setText("上一页");
        }
        prevButton.setToolTipText("上一页");
        prevButton.setPreferredSize(new Dimension(40, 30));
        prevButton.setEnabled(currentPage > 1);
        prevButton.addActionListener(e -> {
            currentPage--;
            refreshData(); // 使用 refreshData 确保数据一致
        });
        paginationPanel.add(prevButton);

        // 显示页码
        if (totalPages <= 5) {
            for (int i = 1; i <= totalPages; i++) {
                addPageButton(i);
            }
        } else {
            int start = Math.max(1, currentPage - 2);
            int end = Math.min(totalPages, currentPage + 2);
            if (start > 1) {
                addPageButton(1);
                if (start > 2) paginationPanel.add(new JLabel("..."));
            }
            for (int i = start; i <= end; i++) {
                addPageButton(i);
            }
            if (end < totalPages) {
                if (end < totalPages - 1) paginationPanel.add(new JLabel("..."));
                addPageButton(totalPages);
            }
        }

        // 下一页按钮
        JButton nextButton = new JButton();
        ImageIcon nextIcon = loadIcon("next.png");
        if (nextIcon != null) {
            nextButton.setIcon(nextIcon);
        } else {
            nextButton.setText("下一页");
        }
        nextButton.setToolTipText("下一页");
        nextButton.setPreferredSize(new Dimension(40, 30));
        nextButton.setEnabled(currentPage < totalPages);
        nextButton.addActionListener(e -> {
            currentPage++;
            refreshData(); // 使用 refreshData 确保数据一致
        });
        paginationPanel.add(nextButton);

        paginationPanel.revalidate();
        paginationPanel.repaint();
    }

    private void addPageButton(int page) {
        JButton pageButton = new JButton(String.valueOf(page));
        if (page == currentPage) {
            pageButton.setEnabled(false);
        }
        pageButton.addActionListener(e -> {
            currentPage = page;
            updateTableData();
            updatePagination();
        });
        paginationPanel.add(pageButton);
    }

    private void updateTableData() {
        DefaultTableModel model = new DefaultTableModel(columnNamesWithCheckbox, 0) {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                if (columnIndex == 0) {
                    return Boolean.class; // 第一列为复选框
                }
                // 为特定列设置数据类型
                switch (columnIndex) {
                    case 1: return Integer.class; // 序号
                    case 15: return Double.class; // 覆盖面积
                    case 16: return Double.class; // 数据量大小
                    case 17: return Integer.class; // 文件个数
                    case 18: return String.class; // 数据是否涉密（显示为“是”/“否”）
                    default: return String.class;
                }
            }
        };


        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        if (currentLedgers == null || currentLedgers.isEmpty()) {
            System.out.println("currentLedgers 为空或无数据");
            table.setModel(model);
            table.revalidate();
            table.repaint();
            return;
        }

        // 新增：为表格头部添加复选框渲染器
        headerCheckBox = new JCheckBox();
        headerCheckBox.setHorizontalAlignment(SwingConstants.CENTER);
        headerCheckBox.addActionListener(e -> {
            boolean selected = headerCheckBox.isSelected();
            for (int i = 0; i < model.getRowCount(); i++) {
                model.setValueAt(selected, i, 0); // 设置当前页所有行的复选框状态
            }
        });
        table.getTableHeader().getColumnModel().getColumn(0).setHeaderRenderer(
                new TableCellRenderer() {
                    @Override
                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                        return headerCheckBox;
                    }
                }
        );


        int start = (currentPage - 1) * rowsPerPage;
        int end = Math.min(start + rowsPerPage, currentLedgers.size());

        if (start >= currentLedgers.size()) {
            currentPage = Math.max(1, (int) Math.ceil((double) currentLedgers.size() / rowsPerPage));
            start = (currentPage - 1) * rowsPerPage;
            end = Math.min(start + rowsPerPage, currentLedgers.size());
        }

        for (int i = start; i < end; i++) {
            Ledger ledger = currentLedgers.get(i);
            Boolean isSelected = checkboxStates.getOrDefault(ledger.getId(), false); // 获取保存的选中状态，默认为 false
            model.addRow(new Object[]{
                    isSelected, // 复选框列，初始为未选中
                    ledger.getSerialNumber(),
                    ledger.getYear(),
                    ledger.getBusinessType(),
                    ledger.getTaskNumber(),
                    ledger.getHandoverNumber(),
                    ledger.getDataIdentifier(),
                    ledger.getPrimaryDirectory(),
                    ledger.getSecondaryDirectory(),
                    ledger.getDataName(),
                    ledger.getControlPlanNumber(),
                    ledger.getControlPlanCode(),
                    ledger.getDataFormat(),
                    ledger.getCoordinateSystem(),
                    ledger.getCoverageArea(),
                    ledger.getCoverageAreaSize(),
                    ledger.getDataSizeMb(),
                    ledger.getFileCount(),
                    ledger.isConfidential() ? "是" : "否",
                    ledger.getSubmissionDate() != null ? dateFormat.format(ledger.getSubmissionDate()) : "",
                    ledger.getSubmitter(),
                    ledger.getSubmissionDepartment(),
                    ledger.getSubmissionMedium(),
                    ledger.getFileStorageLocation(),
                    ledger.getSpatialStorageLocation(),
                    ledger.getReceiver(),
                    ledger.getReceiptTime() != null ? dateFormat.format(ledger.getReceiptTime()) : "",
                    ledger.getStoragePerson(),
                    ledger.getStorageDescription(),
                    ledger.getAuditor(),
                    ledger.getAuditDate() != null ? dateFormat.format(ledger.getAuditDate()) : ""
            });
        }

        // 添加表格编辑监听器
        model.addTableModelListener(e -> {
            if (e.getType() == TableModelEvent.UPDATE) {
                int row = e.getFirstRow();
                int column = e.getColumn();
                int ledgerIndex = (currentPage - 1) * rowsPerPage + row;
                if (ledgerIndex >= currentLedgers.size()) return;
                Ledger ledger = currentLedgers.get(ledgerIndex);
                Object value = model.getValueAt(row, column);
                try {
                    switch (column) {
                        case 0: checkboxStates.put(ledger.getId(), value != null ? (Boolean) value : false); break;
                        case 1: ledger.setSerialNumber(value != null ? Integer.parseInt(value.toString()) : 0); break;
                        case 2: ledger.setYear(value != null ? value.toString() : ""); break;
                        case 3: ledger.setBusinessType(value != null ? value.toString() : ""); break;
                        case 4: ledger.setTaskNumber(value != null ? value.toString() : ""); break;
                        case 5: ledger.setHandoverNumber(value != null ? value.toString() : ""); break;
                        case 6: ledger.setDataIdentifier(value != null ? value.toString() : ""); break;
                        case 7: ledger.setPrimaryDirectory(value != null ? value.toString() : ""); break;
                        case 8: ledger.setSecondaryDirectory(value != null ? value.toString() : ""); break;
                        case 9: ledger.setDataName(value != null ? value.toString() : ""); break;
                        case 10: ledger.setControlPlanNumber(value != null ? value.toString() : ""); break;
                        case 11: ledger.setControlPlanCode(value != null ? value.toString() : ""); break;
                        case 12: ledger.setDataFormat(value != null ? value.toString() : ""); break;
                        case 13: ledger.setCoordinateSystem(value != null ? value.toString() : ""); break;
                        case 14: ledger.setCoverageArea(value != null ? value.toString() : ""); break;
                        case 15: ledger.setCoverageAreaSize(value != null ? Double.parseDouble(value.toString()) : 0.0); break;
                        case 16: ledger.setDataSizeMb(value != null ? Double.parseDouble(value.toString()) : 0.0); break;
                        case 17: ledger.setFileCount(value != null ? Integer.parseInt(value.toString()) : 0); break;
                        case 18: ledger.setConfidential(value != null && (value.toString().equals("是") || value.toString().equalsIgnoreCase("true"))); break;
                        case 19: ledger.setSubmissionDate(value != null && !value.toString().isEmpty() ? dateFormat.parse(value.toString()) : null); break;
                        case 20: ledger.setSubmitter(value != null ? value.toString() : ""); break;
                        case 21: ledger.setSubmissionDepartment(value != null ? value.toString() : ""); break;
                        case 22: ledger.setSubmissionMedium(value != null ? value.toString() : ""); break;
                        case 23: ledger.setFileStorageLocation(value != null ? value.toString() : ""); break;
                        case 24: ledger.setSpatialStorageLocation(value != null ? value.toString() : ""); break;
                        case 25: ledger.setReceiver(value != null ? value.toString() : ""); break;
                        case 26: ledger.setReceiptTime(value != null && !value.toString().isEmpty() ? dateFormat.parse(value.toString()) : null); break;
                        case 27: ledger.setStoragePerson(value != null ? value.toString() : ""); break;
                        case 28: ledger.setStorageDescription(value != null ? value.toString() : ""); break;
                        case 29: ledger.setAuditor(value != null ? value.toString() : ""); break;
                        case 30: ledger.setAuditDate(value != null && !value.toString().isEmpty() ? dateFormat.parse(value.toString()) : null); break;
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(this, "输入格式错误：第 " + (row + 1) + " 行，第 " + (column + 1) + " 列");
                    ex.printStackTrace();
                }
            }
        });

        table.setModel(model);
        table.revalidate();
        table.repaint();
        System.out.println("表格数据更新完成，显示 " + model.getRowCount() + " 行");

    }

    private void refreshData() {
        // 重新从数据库加载数据
        currentLedgers = ledgerDAO.getAllLedgers();
        // 重置到第一页（可选，根据需求决定是否保留当前页）
        currentPage = 1;
        // 更新表格和分页
        updateTableData();
        updatePagination();
    }
}